package org.adorsys.aderp.aderplogin.client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Set;

import org.adorsys.aderp.aderplogin.client.common.Oauth2User;
import org.adorsys.aderp.aderplogin.domain.AderpUser;
import org.adorsys.aderp.aderplogin.domain.UserRole;
import org.adorsys.aderp.aderplogin.roles.ContextualRole;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class UserDetailsHelper {

	public static UserDetails createUserDetails(AderpUser baseAdUser)
			throws UsernameNotFoundException, DataAccessException {
		
		String password = baseAdUser.getPassword();
		
		boolean enabled = !baseAdUser.isDisableLogin();
		
		Date accountExpiration = baseAdUser.getAccountExpiration();
		boolean accountNonExpired = false;
		if (accountExpiration != null) {
			accountNonExpired = new Date().before(accountExpiration);
		}
		Date credentialExpiration = baseAdUser.getCredentialExpiration();
		boolean credentialsNonExpired = false;
		if (credentialExpiration != null) {
			credentialsNonExpired = new Date().before(credentialExpiration);
		}
		boolean accountNonLocked = !baseAdUser.isAccountLocked();

		Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		Set<UserRole> roles = baseAdUser.getRoleNames();
		
		for (UserRole userRole : roles) {
			SimpleGrantedAuthority sa = new SimpleGrantedAuthority(userRole.getRoleKey());
			authorities.add(sa);
			// Spring bug. Add permission profile if context exists.
			String extractPermissionProfile = ContextualRole.extractPermissionProfile(userRole.getRoleKey());
			if(!StringUtils.equals(userRole.getRoleKey(), extractPermissionProfile)){
				authorities.add(new SimpleGrantedAuthority(extractPermissionProfile));
			}
		}
		UserDetails userDetails = new User(baseAdUser.getUserName(), password,
				enabled, accountNonExpired, credentialsNonExpired,
				accountNonLocked, authorities);
		return userDetails;
	}

	public static UserDetails createUserDetails(Oauth2User oauth2User, Authentication clientAuthentication) {
		String selectedRole = oauth2User.getSelectedRole();
		Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		if(StringUtils.isBlank(selectedRole)) selectedRole = "NoRole";
		authorities.add(new SimpleGrantedAuthority(selectedRole));
		String extractPermissionProfile = ContextualRole.extractPermissionProfile(selectedRole);
		authorities.add(new SimpleGrantedAuthority(extractPermissionProfile));
		if(clientAuthentication!=null){
			authorities.add(new ClientAuthority(clientAuthentication));
		}
		authorities.add(new TokenAuthority(oauth2User.getOauthToken()));
		UserDetails userDetails = new User(oauth2User.getUsername(), "NoPassword",
				true, true, true,
				true, authorities);
		return userDetails;
	}
}
